#pragma once

#include <iostream>
#include <sys/epoll.h>

#include "log.hpp"
#include "Common.hpp"

using namespace LogModule;

namespace EpollModule
{
    // 定义Epoller类，用于封装epoll文件描述符及其操作
    class Epoller
    {
    public:
        Epoller() : _epfd(-1)
        {
        }
        // 初始化方法，用于创建epoll文件描述符
        void Init()
        {
            _epfd = epoll_create(256);
            if (_epfd < 0)
            {
                LOG(ERROR, "epoll_create error!\n");
                exit(EPOLL_CREATE_ERROR);
            }
            LOG(INFO, "epoll_create success! epfd: %d\n", _epfd);
        }

        // 等待方法，用于等待事件发生
        int wait(struct epoll_event revs[], int num, int timeout) // 输出就绪的fd和events
        {
            int n = epoll_wait(_epfd, revs, num, timeout); // -1表示无限期等待
            if (n < 0)
            {
                LOG(WARNING, "epoll_waite error!\n");
            }
            return n;
        }

        // 控制方法，用于控制事件发生
        void Ctrl(int sockfd, uint32_t events, int flag)
        {
            struct epoll_event ev;
            ev.events = events;
            ev.data.fd = sockfd;
            int n = epoll_ctl(_epfd, flag, sockfd, &ev);
            if (n < 0)
            {
                LOG(ERROR, "epoll_ctl error!\n");
            }
        }

        void Add(int sockfd, uint32_t events)
        {
            Ctrl(sockfd, events, EPOLL_CTL_ADD);
        }

        void UpDate(int sockfd, uint32_t events)
        {
            Ctrl(sockfd, events, EPOLL_CTL_MOD);
        }

        void Delete(int sockfd)
        {
            int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr);
            if (n < 0)
            {
                LOG(WARNING, "epoll_ctl error\n");
            }
        }

        ~Epoller()
        {
        }

    private:
        int _epfd;
    };
};